package com.icoolkj.ms.auth.controller;

import com.icoolkj.ms.api.auth.dto.CaptchaDTO;
import com.icoolkj.ms.api.rbac.dto.ClearUserPermissionsCacheDTO;
import com.icoolkj.ms.api.auth.bo.UserInfoInTokenBO;
import com.icoolkj.ms.api.rbac.feign.PermissionFeignClient;
import com.icoolkj.ms.auth.dto.AuthenticationDTO;
import com.icoolkj.ms.auth.enums.LoginTypeEnum;
import com.icoolkj.ms.auth.manager.TokenManager;
import com.icoolkj.ms.auth.service.IAuthAccountService;
import com.icoolkj.ms.api.auth.vo.TokenInfoVO;
import com.icoolkj.ms.auth.service.IAuthStrategy;
import com.icoolkj.ms.common.core.enums.ResponseEnum;
import com.icoolkj.ms.common.core.exception.IcoolkjMSException;
import com.icoolkj.ms.common.core.response.ServerResponseEntity;
import com.icoolkj.ms.common.security.AuthUserContext;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author icoolkj
 * @version 1.0
 * @description 登录
 * @createDate 2025/02/03 21:53
 */
@Tag(name = "认证服务", description = "提供用户名密码、手机号、邮箱三种登录方式")
@RestController
public class LoginController {

    private static final Logger logger = LoggerFactory.getLogger(LoginController.class);

    @Autowired
    private TokenManager tokenManager;

    @Autowired
    private IAuthAccountService iAuthAccountService;

    @Autowired
    private PermissionFeignClient permissionFeignClient;

    @PostMapping("/public/login")
    @Operation(summary = "用户登录", description = "支持用户名密码、手机号验证码、邮箱验证码三种登录方式")
    public ServerResponseEntity<TokenInfoVO> login(@Valid @RequestBody AuthenticationDTO authenticationDTO) {
        // 根据登录类型进行不同的验证
        Integer loginType = authenticationDTO.getLoginType();
        if (loginType == null) {
            return ServerResponseEntity.fail("登录类型不能为空");
        }

        // 验证码校验
        boolean validateRes = false;
        ServerResponseEntity<UserInfoInTokenBO> userInfoInTokenResponse = null;

        try {
            // 根据登录类型进行不同的验证
            if (LoginTypeEnum.USERNAME_PASSWORD.getCode().equals(loginType)) {
                // 用户名密码登录
                if (authenticationDTO.getUserName() == null || authenticationDTO.getPassword() == null) {
                    return ServerResponseEntity.fail("用户名和密码不能为空");
                }
                
                // 验证图形验证码
                CaptchaDTO captchaDTO = new CaptchaDTO();
                captchaDTO.setCaptcha(authenticationDTO.getCaptcha());
                captchaDTO.setUuid(authenticationDTO.getUuid());
                validateRes = IAuthStrategy.validateCodeByGrantType("uuid", captchaDTO);
                
                if (!validateRes) {
                    return ServerResponseEntity.fail("验证码校验失败");
                }
                
                // 验证用户名密码
                userInfoInTokenResponse = iAuthAccountService.getUserInfoInTokenByInputUserNameAndPassword(
                        authenticationDTO.getUserName(),
                        authenticationDTO.getPassword(),
                        authenticationDTO.getUserType());
                
            } else if (LoginTypeEnum.PHONE_CODE.getCode().equals(loginType)) {
                // 手机号验证码登录
                if (authenticationDTO.getPhoneNumber() == null) {
                    return ServerResponseEntity.fail("手机号不能为空");
                }
                
                // 验证短信验证码
                CaptchaDTO captchaDTO = new CaptchaDTO();
                captchaDTO.setCaptcha(authenticationDTO.getCaptcha());
                captchaDTO.setPhoneNumber(authenticationDTO.getPhoneNumber());
                validateRes = IAuthStrategy.validateCodeByGrantType("sms", captchaDTO);
                
                if (!validateRes) {
                    return ServerResponseEntity.fail("验证码校验失败");
                }
                
                // 根据手机号获取用户信息
                userInfoInTokenResponse = iAuthAccountService.getUserInfoInTokenByPhone(
                        authenticationDTO.getPhoneNumber(),
                        authenticationDTO.getUserType());
                
            } else if (LoginTypeEnum.EMAIL_CODE.getCode().equals(loginType)) {
                // 邮箱验证码登录
                if (authenticationDTO.getEmail() == null) {
                    return ServerResponseEntity.fail("邮箱不能为空");
                }
                
                // 验证邮箱验证码
                CaptchaDTO captchaDTO = new CaptchaDTO();
                captchaDTO.setCaptcha(authenticationDTO.getCaptcha());
                captchaDTO.setEmail(authenticationDTO.getEmail());
                validateRes = IAuthStrategy.validateCodeByGrantType("email", captchaDTO);
                
                if (!validateRes) {
                    return ServerResponseEntity.fail("验证码校验失败");
                }
                
                // 根据邮箱获取用户信息
                userInfoInTokenResponse = iAuthAccountService.getUserInfoInTokenByEmail(
                        authenticationDTO.getEmail(),
                        authenticationDTO.getUserType());
                
            } else {
                return ServerResponseEntity.fail("不支持的登录类型");
            }
        } catch (IcoolkjMSException e) {
            logger.error("登录验证失败", e);
            return ServerResponseEntity.fail(e.getMessage());
        } catch (Exception e) {
            logger.error("登录过程发生异常", e);
            return ServerResponseEntity.fail("登录失败，请稍后再试");
        }

        if (userInfoInTokenResponse == null || !userInfoInTokenResponse.isSuccess()) {
            return ServerResponseEntity.transform(userInfoInTokenResponse != null ? 
                    userInfoInTokenResponse : ServerResponseEntity.fail("用户信息获取失败"));
        }

        UserInfoInTokenBO userInfoInTokenBO = userInfoInTokenResponse.getData();

        ClearUserPermissionsCacheDTO clearUserPermissionsCacheDTO = new ClearUserPermissionsCacheDTO();
        clearUserPermissionsCacheDTO.setUserId(userInfoInTokenBO.getUserId());
        clearUserPermissionsCacheDTO.setUserType(userInfoInTokenBO.getUserType());
        // 将以前的权限清理了，以免权限有缓存
        ServerResponseEntity<Void> clearResponseEntity = permissionFeignClient.clearUserPermissionsCache(clearUserPermissionsCacheDTO);

        if (!clearResponseEntity.isSuccess()) {
            return ServerResponseEntity.fail(ResponseEnum.UNAUTHORIZED);
        }

        // 保存token，返回token信息
        return ServerResponseEntity.success(tokenManager.storeAndGetVo(userInfoInTokenBO));
    }

    @PostMapping("/logout")
    @Operation(summary = "退出登录" , description = "点击退出登录，清除token，清除菜单缓存")
    public ServerResponseEntity<TokenInfoVO> loginOut() {
        UserInfoInTokenBO userInfoInToken = AuthUserContext.get();
        ClearUserPermissionsCacheDTO clearUserPermissionsCacheDTO = new ClearUserPermissionsCacheDTO();
        clearUserPermissionsCacheDTO.setUserType(userInfoInToken.getUserType());
        clearUserPermissionsCacheDTO.setUserId(userInfoInToken.getUserId());
        // 将以前的权限清理了,以免权限有缓存
        permissionFeignClient.clearUserPermissionsCache(clearUserPermissionsCacheDTO);
        // 删除该用户在该系统的token
        tokenManager.deleteAllToken(userInfoInToken.getUserType(), userInfoInToken.getUid());
        return ServerResponseEntity.success();
    }

}
